﻿/*****************************************************************
 * @file vol_acqu.c
 * @brief 电压采集  PA0脚  ADC0常规通道连续模式+DMA
 *****************************************************************
 */

#include "adc.h"
#include "dma.h"
#include "sys.h"
#include "vol_acqu.h"
#include <string.h>
#include <stdbool.h>
#include "FreeRTOS.h"
#include "semphr.h"


#define REFV                   (3.3f)                        /* ADC参考电压 */
#define D2V(x)                 ((x) / 4095.0f * REFV) /* 将采集到的数字量转换为具体的电压值 V */
#define INVERSE_OF_DIFF_AMP(x) (((x) - 1.66666f) / 8.0f) /* 做差分放大的逆运算 求出放大前电压 */

uint8_t adcBufferFull = 0; /*!< 0:未满  1:buffer0满 2:buffer1满 */
bool adcArrayEmpty = true;
uint16_t adcValueBuffer[2][ADC_BUFFER_LEN] = { 0 };
uint16_t adcValueArray[ADC_BUFFER_LEN] = { 0 };

/**
 * @brief 初始化电压采集(自动初始化)
 */
void VolAcquInit(void)
{
    Adc0Config();
    Adc0GpioConfig();
    Dma0ConfigForAdc0(adcValueBuffer[0], ADC_BUFFER_LEN * 2);
    Dma0ConfigForAdcDump(adcValueBuffer[0], adcValueArray, ADC_BUFFER_LEN);
}
INIT_BSP_EXPORT(VolAcquInit);


/**
 * @brief 获取电压采样值(差分放大之前 衰减之后) V
 * @return 电压缓存区地址 ADC_BUFFER_LEN个元素
 */
float *VolAcquGetValue(void)
{
    if(adcArrayEmpty) return NULL;

    __disable_irq();
    uint16_t temp[ADC_BUFFER_LEN] = { 0 };
    memcpy(temp, adcValueArray, ADC_BUFFER_LEN * sizeof(uint16_t));
    adcArrayEmpty = true;
    __enable_irq();

    static float voltage[ADC_BUFFER_LEN] = { 0.0f };
    for(int i = 0; i < ADC_BUFFER_LEN; i++)
    {
        voltage[i] = D2V(temp[i]); /* 电压值 */
        voltage[i] = INVERSE_OF_DIFF_AMP(voltage[i]); /* 做差分放大前电压值 */
    }

    return voltage;
}


void dma_transfer_complete_callback_it(uint32_t dma_periph, dma_channel_enum channel)
{
    if(DMA0 == dma_periph)
    {
        if(DMA_CH0 == channel)
        {
            adcBufferFull++;
            adcBufferFull %= 3;

            if(adcBufferFull)
            {
                /* 启动DMA通道3传输 */
                dma_channel_disable(DMA0, DMA_CH3);
                dma_periph_address_config(DMA0, DMA_CH3, (uint32_t)adcValueBuffer[--adcBufferFull]);
                dma_transfer_number_config(DMA0, DMA_CH3, ADC_BUFFER_LEN);
                dma_channel_enable(DMA0, DMA_CH3);
            }
        }
        if(DMA_CH3 == channel)
        {
            adcArrayEmpty = false;
        }
    }
}

void dma_transfer_half_callback_it(uint32_t dma_periph, dma_channel_enum channel)
{
    if(DMA0 == dma_periph)
    {
        if(DMA_CH0 == channel)
        {
            adcBufferFull++;
            adcBufferFull %= 3;

            if(adcBufferFull && adcArrayEmpty)
            {
                /* 启动DMA通道3传输 */
                dma_channel_disable(DMA0, DMA_CH3);
                dma_periph_address_config(DMA0, DMA_CH3, (uint32_t)adcValueBuffer[--adcBufferFull]);
                dma_transfer_number_config(DMA0, DMA_CH3, ADC_BUFFER_LEN);
                dma_channel_enable(DMA0, DMA_CH3);
            }
        }
    }
}
